package cgo

import (
	"gitee.com/hasika/gotool/generic"
	"unsafe"
)

var sizeof = unsafe.Sizeof(uintptr(0))

type ArrayImpl interface {
	~uintptr
	IndexArray(n int) uintptr
	DeleteArray()
}

type Array[T ArrayImpl] uintptr

//go:force inline
func (a Array[T]) Index(n int) T {
	ret := T(a)
	return T(ret.IndexArray(n))
}

//go:force inline
func (a Array[T]) Delete() {
	ret := T(a)
	ret.DeleteArray()
}

type PointerArray[T ArrayImpl] uintptr

//go:force inline
func (a PointerArray[T]) Index(n int64) T {
	return T(uintptr(a) + uintptr(n)*sizeof)
}

//go:force inline
func ToArray[T ArrayImpl](ptr T) Array[T] {
	return Array[T](ptr)
}

//go:force inline
func ToPointerArray[T generic.Primitive](m *T, size int) []T {
	if m == nil {
		return nil
	}
	ret := (*[1 << 30]T)(unsafe.Pointer(m))[:size]
	return ret
}

//go:force inline
func CopyGoArrayToCPointer[T generic.Primitive](source []T, target uintptr) {
	if source == nil {
		return
	}
	copy((*[1 << 30]T)(unsafe.Pointer(target))[:len(source)], source)
}
